﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Othello_Game
{
    /// <summary>
    /// This class manages the program's general constants and values
    /// </summary>
    public class GeneralConsts
    {
        #region General Consts
        /// <summary>
        /// The const for a legal Othello board size.
        /// </summary>
        public const byte LEGAL_BOARD_SIZE = 8;
        #endregion

        #region public Properties
        /// <summary>
        /// Gets an Othello_Game.IPositionsValues to calculate the board's positions values.
        /// </summary>
        public IPositionsValues PositionsValues { get; private set; }

        /// <summary>
        /// Gets an Othello_Game.IComparer to compare between two Othello_Game.ActionList's values
        /// </summary>
        public IComparer<ActionList> ActionsListComparer { get; private set; }

        /// <summary>
        /// Gets the total number of available spots on the game board.
        /// </summary>
        public int TotalBoardPlaces { get; private set; }

        /// <summary>
        /// Gets the Othello_Game.IReinforcementLearningAlgorithm to calculate 
        /// the best move to play
        /// </summary>
        public IReinforcementLearningAlgorithm LearningAlgorithm { get; private set; }

        /// <summary>
        /// Gets a list of Othello_Game.IAttributeNormalizedValues that are 
        /// used to calculate the values of moves in the game
        /// </summary>
        public List<IAttributeNormalizedValues> AttributesList { get; private set; }

        /// <summary>
        /// Gets and Sets the WeightVector used to calculate the values of
        /// moves in the game
        /// </summary>
        public WeightVector AttributeWeights { get; set; }

        public static Random random = new Random();

        #endregion

        #region Private Ctor
        /// <summary>
        /// Initializes a new instance of the Othello_Game.GeneralConsts class
        /// </summary>
        private GeneralConsts()
        {
            // Initialize a new instance of the Othello_Game.IPositionsValues
            this.PositionsValues = new BoardPositionsValues(LEGAL_BOARD_SIZE);

            // Initialize a new instance of the Othello_Game.IComparer<ActionList>
            this.ActionsListComparer = new CompareActionListValues();

            this.TotalBoardPlaces = (int)Math.Pow(GeneralConsts.LEGAL_BOARD_SIZE, 2);

            this.LearningAlgorithm = new MinMaxTreeSearch();

            // Initialize the Attributes list
            this.AttributesList = new List<IAttributeNormalizedValues>();
            this.AttributesList.Add(new PossibleMovesNumAttribute());
            this.AttributesList.Add(new PlayersPiecesDifferenceAttribute());
            this.AttributesList.Add(new CornerConqueredAttribute());
            this.AttributesList.Add(new PositionValueAttribute());
            this.AttributesList.Add(new RelativePlayerPiecesNumAttribute());

            // Set the WeightVector with the values tested to be most efficiant
            // by letting the computer "duel" himself, useing diffrent weight vectors
            this.AttributeWeights = new WeightVector(new double[]{0.1, 0.5, 0.05, 0.3, 0.05});
        }
        #endregion

        #region Othello_Game.GeneralConsts Singelton
        /// <summary>
        /// The Othello_Game.GeneralConsts singelton
        /// </summary>
        private static GeneralConsts generalConst = null;

        /// <summary>
        /// Gets a static singelton instance of the Othello_Game.GeneralConsts class
        /// </summary>
        public static GeneralConsts Instance
        {
            get    
            {
                if (generalConst == null)
                {
                    // If null initialize a new instance
                    generalConst = new GeneralConsts();
                }

                return generalConst;
            }
        }
        #endregion
    }
}
